/*
   Copyright 2008, Andres Postiglioni

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package com.aconcagua.factory {
  import com.aconcagua.beans.BeanDefinition;

  /**
   * @author Andres Postiglioni
   */
  public interface BeanFactory {
    function getBean(name: String): *;
    /**
     * Does this bean factory contain a bean with the given name? More specifically,
     * is <a href="#getBean()">getBean</a> able to obtain a bean instance for the given name?
     * <p>Translates aliases back to the corresponding canonical bean name.
     * @param name the name of the bean to query
     * @return whether a bean with the given name is defined
     */
    function containsBean(name: String): Boolean

    function registerBeanDefinition(bean: BeanDefinition): void

    function registerAlias(alias: String, bean: BeanDefinition): void

  /**
   * Is this bean a shared singleton? That is, will <a href="#getBean()">getBean</a> always
   * return the same instance?
   * <p>Translates aliases back to the corresponding canonical bean name.
   * @param name the name of the bean to query
   * @return whether this bean corresponds to a singleton instance
   * @throws NoSuchBeanDefinitionException if there is no bean with the given name
   * @see #getBean()
   * @see #isPrototype()
   */
  function isSingleton(name: String): Boolean;

  /**
   * Is this bean a prototype? That is, will <a href="#getBean()">getBean</a> always return
   * independent instances?
   * <p>Translates aliases back to the corresponding canonical bean name.
   * @param name the name of the bean to query
   * @return whether this bean will always deliver independent instances
   * @throws NoSuchBeanDefinitionException if there is no bean with the given name
   * @see #getBean()
   * @see #isSingleton()
   */
  function isPrototype(name: String): Boolean;

  /**
   * Check whether the bean with the given name matches the specified type.
   * More specifically, check whether a <a href="#getBean()">getBean</a> call for the given name
   * would return an object that is assignable to the specified target type.
   * <p>Translates aliases back to the corresponding canonical bean name.
   * Will ask the parent factory if the bean cannot be found in this factory instance.
   * @param name the name of the bean to query
   * @param targetType the type to match against
   * @return <code>true</code> if the bean type matches,
   * <code>false</code> if it doesn't match or cannot be determined yet
   * @throws NoSuchBeanDefinitionException if there is no bean with the given name
   * @see #getBean()
   * @see #getType()
   */
  function isTypeMatch(name: String, targetType: Class): Boolean;

  /**
   * Determine the type of the bean with the given name. More specifically,
   * determine the type of object that <a href="#getBean()">getBean</a> would return for the given name.
   * <p>For a <a href="../beans/FactoryBean.html">FactoryBean</a>, return the type of object that the FactoryBean creates,
   * as exposed by <a href="../beans/FactoryBean.html#getObjectType()">FactoryBean#getObjectType()</a>.
   * <p>Translates aliases back to the corresponding canonical bean name.
   * Will ask the parent factory if the bean cannot be found in this factory instance.
   * @param name the name of the bean to query
   * @return the type of the bean, or <code>null</code> if not determinable
   * @throws NoSuchBeanDefinitionException if there is no bean with the given name
   * @see #getBean()
   * @see #isTypeMatch()
   */
  function getType(name: String): Class;

  /**
   * Return the aliases for the given bean name, if any.
   * All of those aliases point to the same bean when used in a <a href="#getBean()">getBean</a> call.
   * <p>If the given name is an alias, the corresponding original bean name
   * and other aliases (if any) will be returned, with the original bean name
   * being the first element in the array.
   * @param name the bean name to check for aliases
   * @return the aliases, or an empty array if none
   * @see #getBean()
   */
  function getAliases(name: String): Array;

  }
}